package com.wt.springsamples.redis;

import org.redisson.Redisson;
import org.redisson.RedissonRedLock;
import org.redisson.api.RFencedLock;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

//@SpringBootApplication
public class RedisSamplesApplication {
    public static void main(String[] args) throws InterruptedException {
//        RedissonClient  redisson = Redisson.create();
        ApplicationContext applicationContext = SpringApplication.run(RedisSamplesApplication.class, args);

        RedissonClient redissonClient = applicationContext.getBean(RedissonClient.class);
        RedisTemplate redisTemplate = applicationContext.getBean("redisTemplate",RedisTemplate.class);
        StringRedisTemplate stringRedisTemplate = applicationContext.getBean(StringRedisTemplate.class);
        int i=0;
        while (true){
            TimeUnit.SECONDS.sleep(1);
            i++;
            stringRedisTemplate.opsForValue().set("key"+i,"value"+i,5,TimeUnit.MINUTES);
//            try{
//                //手动停止集群主节点后，程序会崩溃，需要捕获异常
//                stringRedisTemplate.opsForValue().set("key"+i,"value"+i,5,TimeUnit.MINUTES);
//            }catch (Exception e){
//                e.printStackTrace();
//            }

            System.out.println(stringRedisTemplate.opsForValue().get("key"+i));
        }
//        RLock lock =  redissonClient.getLock("lockKey");
        //lock.lock();//默认30秒
        /**
         * 对应Redis数据类型为hash,命令：hkeys lockKey得到类似值76b9ecc1-14b7-4d88-90e6-d7937da48bd1:1表示获取该锁所有的Key
         * 多次加锁，会导致hash中对应key对应的value值递增
         */
//        lock.lock(5, TimeUnit.SECONDS);
//        lock.lock(5, TimeUnit.SECONDS);

//        lock.lock(5, TimeUnit.MINUTES);
//        try{
//            System.out.println("key name=>"+lock.getName());
//            System.out.println("HoldCount=>"+lock.getHoldCount());
//            Map<String,Object> lockKeyMap = redisTemplate.opsForHash().entries("lockKey");
//            stringRedisTemplate.opsForValue().set("key1","value1",5,TimeUnit.MINUTES);
//            System.out.println("k1 =>"+stringRedisTemplate.opsForValue().get("k1"));
//            System.out.println("key1 =>"+stringRedisTemplate.opsForValue().get("key1"));
//            for(Map.Entry<String,Object> entry:lockKeyMap.entrySet()){
//                System.out.println("lockKey hash key=>"+entry.getKey());
//                System.out.println("lockKey hash value=>"+entry.getValue());
//            }
            /**
             * 输出：
             * key name=>lockKey
             * HoldCount=>2
             * k1 =>v1
             * key=>90f25b70-ef21-42e9-a9bc-6a9b24ac81f6:1
             * value=>2
             */
//        }  finally {
//            if(lock.isLocked() && lock.isHeldByCurrentThread()){
//                while (lock.getHoldCount()>0){
//                    lock.unlock();
//                }
//            }
//        }

//        RLock tryLock =  redissonClient.getLock("tryLock");
//        try {
//            if(tryLock.tryLock(5,TimeUnit.SECONDS)){
//                //do
//            }
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        } finally {
//            if(tryLock.isLocked() && tryLock.isHeldByCurrentThread()){
//                tryLock.unlock();
//            }
//        }

        //红锁，可以将一个多个RLock对象关联为一个红锁,继承自联锁RedissonMultiLock
//        RedissonRedLock redLock = new RedissonRedLock(redissonClient.getLock("redLock"));
//        redLock.lock(5,TimeUnit.MINUTES);
//        try {
//
//        }finally {
//            redLock.unlock();
//        }
//        围栏锁
//        RFencedLock fencedLock = redissonClient.getFencedLock("fencedLock");
//        Long token = fencedLock.lockAndGetToken(10, TimeUnit.SECONDS);
//        System.out.println("fencedLock token>"+token);
//        if (token != null) {
//            try {
//                // check if token >= old token
//            } finally {
//                fencedLock.unlock();
//            }
//        }
    }
}
